;;;Author unknown
;;;Gets Drawing Properties
;;;
(defun C:GetDwgProps ( / ;dict
			 title
			 subject
			 author
			 comments
			 keywords
			 hyperlink
			 lastSavedBy
			 revision
			 editingTime
			 createdAt
			 modifiedAt
			 numberOfCustProps
			 counter
			 custVar)
 
 ;; Get the named object dictionary and remove everything
 ;; before the "DWGPROPS" entry.
 (setq dict (member '(3 . "DWGPROPS") (entget (namedobjdict))))

 ;; Examine the properties (if the dictionary is there)
 (if (/= dict nil)
   (progn
     
     ;; Get the dictionary of "DWGPROPS"
     (setq dict (entget (cdr (nth 1 dict))))

     ;; Get the DWGPROPS.
     (setq title (cdr (assoc 2 dict))
	    subject (cdr (assoc 3 dict))
	    author (cdr (assoc 4 dict))
	    comments (cdr (assoc 6 dict))
	    keywords (cdr (assoc 7 dict))
	    hyperlink (cdr (assoc 1 (reverse dict)))
	    lastSavedBy (cdr (assoc 8 dict))
	    revision (cdr (assoc 9 dict))
	    editingTime (cdr (assoc 40 dict))
	    createdAt (cdr (assoc 41 dict))
	    modifiedAt (cdr (assoc 42 dict))
	    numberOfCustProps (cdr (assoc 90 dict))
     )
     (princ "\nActual DWG properties:")
     (princ "\nTitle:\t") (princ title)
     (princ "\nSubject:\t") (princ subject)
     (princ "\nAuthor:\t") (princ author)
     (princ "\nComments:\t") (princ comments)
     (princ "\nKeywords:\t") (princ keywords)
     (princ "\nHyperlink:\t") (princ hyperlink)
     
     (princ "\n\nStatistic:")
     (princ "\nLast saved by:\t") (princ lastSavedBy)
     (princ "\nRevision:\t") (princ revision)
     (princ "\nEditing time:\t") (princ (GetEditTime editingTime))
     (princ "\nCreation date: \t") (princ createdAt)
     (princ "\nLast modififed at: \t") (princ modifiedAt)

     (princ "\n\nCustom properties (")
     (princ numberOfCustProps)
     (princ "):")
     (setq counter 0)
     (while (< counter 10)
	(setq custVar (GetCustomVar dict counter))
	(if (/= custVar nil)
	  (progn
	    (princ "\nVar #")
	    (princ (1+ counter))
	    (princ ": ")
	    (princ (nth 0 custVar))
	    (princ "\tValue. ")
	    (princ (nth 1 custVar))
	  )
	)
	(setq counter (1+ counter))
     )
   )
 )

 (princ)
)
;; This function returns a list containing a custom	 
;; variable name and the value of it:			 
;;							 
;; (<var_name> <var_value>)				 
;;							 
;; The parameters are the list of the			 
;; "DWGPROPS" dictionary and the index of the custom var 
;; to extract.						 
(defun GetCustomVar (dict number / code var index)
 (setq code (+ 300 number)
	var (cdr (assoc code dict))
 )
 (if (equal var "=")
   (setq var nil)
   ;; else
   (progn
     (setq index (vl-string-search "=" var)
	    var (list (substr var 1 index) (substr var (+ index 2)))
     )
   )
 )
 var
)

;; This functions returns a string from the 'julianDate'
;; parameter in the following form:			
;;							
;; xx days, xx hour, xx min, xx sec.			
;;							
(defun GetEditTime (julianDate / seconds
				 minutes
				 hours
				 days
				 str)
 (setq seconds (* 86400.0 (- julianDate (fix julianDate)))
	minutes (/ seconds 60)
	hours (/ minutes 60)
	days (/ hours 24)
	str ""
 )
 (if (>= days 1.0)
   (progn
     (setq days (fix days)
	    hours (- hours (* 24 days))
	    minutes (- minutes (* (* 24 days) 60))
	    seconds (- seconds (* (* (* 24 days) 60) 60))
     )
     (setq str (strcat (itoa days) " day(s), "))
   )
 )
 (if (>= hours 1.0)
   (progn
     (setq hours (fix hours)
	    minutes (- minutes (* hours 60))
	    seconds (- seconds (* (* hours 60) 60))
     )
     (setq str (strcat str (itoa hours) " hour(s), "))
   )
 )
 (if (>= minutes 1.0)
   (progn
     (setq minutes (fix minutes)
	    seconds (- seconds (* minutes 60))
     )
     (setq str (strcat str (itoa minutes) " minute(s), "))
   )
 )
 
 (setq seconds (fix seconds))
 
 (setq str (strcat str (itoa seconds) " second(s)"))
 
 str
)